<template>
  <div class="add-product">
    <nav-bar :left-text="'取消'">
      <div class="push-btn" @click="onPublish">发布</div>
    </nav-bar>
    <div class="main">
      <van-form ref="formRef">
        <van-cell-group inset>
          <van-field
            v-model="name"
            name="name"
            label="产品名称"
            placeholder="请输入产品名称"
            :rules="formRule.productName"
          />
          <van-field
            v-model="categoryName"
            is-link
            readonly
            name="picker"
            label="种类"
            placeholder="请选择产品种类"
            @click="showPicker = true"
          />
          <van-popup v-model:show="showPicker" position="bottom">
            <van-picker
              :columns="columns"
              @confirm="onConfirm"
              @cancel="showPicker = false"
            />
          </van-popup>
          <van-field
            name="oldPrice"
            label="原价"
            type="digit"
            placeholder="请输入原价"
            v-model="oldPrice"
            :rules="formRule.oldPrice"
          />
          <van-field
            name="newPrice"
            label="现价"
            type="digit"
            placeholder="请输入现价"
            v-model="newPrice"
            :rules="formRule.newPrice"
          />
          <van-field
            v-model="description"
            type="textarea"
            name="desc"
            label="描述"
            rows="5"
            placeholder="产品描述"
            :rules="formRule.description"
          />
          <van-field name="uploader" label="文件上传">
            <template #input>
              <van-uploader
                v-model="fileList"
                :after-read="onAfterRead"
                :before-delete="onBeforeDelete"
              />
            </template>
          </van-field>
        </van-cell-group>
      </van-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { FormInstance, Toast, UploaderFileListItem } from 'vant'
import * as qiniu from 'qiniu-js'
import NavBar from '../../../components/nav-bar.vue'
import { getCategorys } from '../../../service/category'
import { categorysRes } from '../../../service/category/types'
import { getUploadToken } from '../../../service/upload'
import { formRule } from '../../../utils/form-rule'
import {
  createProduct,
  getProduct,
  updateProductById
} from '../../../service/product'

const route = useRoute()
const router = useRouter()
const formRef = ref<FormInstance>()
const name = ref<string>('')
const description = ref<string>('')
const oldPrice = ref<number>()
const newPrice = ref<number>()
const imgList = ref<string[]>([])
const categoryId = ref<number>()
const category = ref<categorysRes.Category[]>()
const categoryName = ref<string>()
const showPicker = ref<boolean>(false)
const fileList = ref<UploaderFileListItem[]>([])
const columns = ref<string[]>([])
const uploadToken = ref<string>('')
const isEdit = ref<boolean>(false)
const productId = ref<number>(0)

const onBeforeDelete = (
  file: File,
  detail: { name: string; index: number }
) => {
  imgList.value.splice(detail.index, 1)
  return true
}
const onAfterRead = async (
  items: UploaderFileListItem | UploaderFileListItem[]
) => {
  const item = items as UploaderFileListItem
  item.status = 'uploading'
  if (!item.file) return
  if (!uploadToken.value) {
    const res = await getUploadToken()
    uploadToken.value = res.data.uploadToken
  }
  qiniu
    .compressImage(item.file, {
      quality: 0.2,
      noCompressIfLarger: true
    })
    .then((data) => {
      const observable = qiniu.upload(
        data.dist as File,
        null,
        uploadToken.value
      )
      observable.subscribe({
        error() {
          item.status = 'failed'
        },
        complete(res) {
          imgList.value.push(res.url)
          item.status = 'done'
        }
      })
    })
}
const onConfirm = (name: string) => {
  categoryName.value = name
  const cate = category.value?.find((item) => item.name === name)
  categoryId.value = cate?.id
  showPicker.value = false
}
const onPublish = () => {
  formRef.value?.validate().then(async () => {
    if (!categoryId.value) {
      Toast('请选择产品分类')
      return
    }
    if (!newPrice.value || !oldPrice.value) return
    if (isEdit.value) {
      const res = await updateProductById(productId.value, {
        categoryId: categoryId.value,
        name: name.value,
        description: description.value,
        oldPrice: oldPrice.value,
        newPrice: newPrice.value,
        imgList: imgList.value
      })
      router.push(`/product/${res.data.product.id}`)
    } else {
      const res = await createProduct({
        categoryId: categoryId.value,
        name: name.value,
        description: description.value,
        oldPrice: oldPrice.value,
        newPrice: newPrice.value,
        imgList: imgList.value
      })
      router.push(`/product/${res.data.product.id}`)
    }
  })
}
const loadCategorys = async () => {
  const res = await getCategorys()
  category.value = res.data.categorys
  res.data.categorys.forEach((item) => {
    columns.value.push(item.name)
  })
}
const loadProduct = async (id: number) => {
  const res = await getProduct(id)
  name.value = res.data.product.name
  description.value = res.data.product.description
  oldPrice.value = res.data.product.oldPrice
  newPrice.value = res.data.product.newPrice
  imgList.value = res.data.product.imgList
  categoryId.value = res.data.product.categoryId
  productId.value = res.data.product.id
  if (!category.value) return
  category.value.map((item) => {
    if (item.id === res.data.product.categoryId) {
      categoryName.value = item.name
    }
  })
  imgList.value.map((item) => {
    fileList.value?.push({
      url: item,
      isImage: true
    })
  })
}

onMounted(() => {
  loadCategorys().then(() => {
    if (route.params.id) {
      isEdit.value = true
      const id = route.params.id as unknown as number
      loadProduct(id)
    }
  })
})
</script>

<style lang="scss" scoped>
.add-product {
  height: 100%;
  background-color: #fff;
  .push-btn {
    color: #48a0fc;
  }
}
</style>
